package com.xiye.common.session.shiro;

import java.util.Collection;

import com.xiye.common.session.redis.RedisSessionDAO;
import com.xiye.common.util.Const;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @author 西野
 * @version V1.0
 * @title ShiroRealm.java
 * @package com.xiye.common.session.shiro
 * @description ShiroRealm
 * @date 2018-07-12
 */
public class ShiroRealm extends AuthorizingRealm {

    @Autowired
    RedisSessionDAO redisSessionDAO;

    // 清空
    protected void doClearCache(PrincipalCollection principals) {
        super.doClearCache(principals);
        this.clearCachedAuthorizationInfo(principals);
    }

    // 修改key的值
    public Object getAuthorizationCacheKey(PrincipalCollection principals) {
        Collection<?> collection = principals.fromRealm(getName());
        if (collection == null || collection.isEmpty()) {
            return null;
        }
        Object username = collection.iterator().next();
        return username;
    }

    /**
     * @return
     * @title AuthenticationInfo
     * @description 登录信息和用户验证信息验证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = (String) token.getPrincipal(); // 得到用户名
        String password = new String((char[]) token.getCredentials()); // 得到密码
        Collection<Session> sessions = redisSessionDAO.getActiveSessions();// 获取session列表
        /* shiro 实现redis共享session， 一个用户只能在一处登录，后登陆的用户会顶掉之前的用户session */
        if (null != username && null != password) {
            if (sessions.size() > 0) {
                for (Session session : sessions) {
                    //获得session中已经登录用户的名字
                    if (null != session.getAttribute(Const.SESSION_USERNAME)) {
                        String loginUsername = session.getAttribute(Const.SESSION_USERNAME).toString();
                        if (username.equals(loginUsername)) {  // 这里的username也就是当前登录的username
                            redisSessionDAO.delete(session);// 这里就把session清除，
                            //session.setTimeout(0);  //这里就把session清除，
                        }
                    }
                }
            }
            return new SimpleAuthenticationInfo(username, password, getName());
        } else {
            return null;
        }
    }

    /**
     * @return
     * @title AuthorizationInfo
     * @description 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用,负责在应用程序中决定用户的访问控制的方法
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
        return null;
    }
}
